package org.jeemp.test.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author: rht
 * @date: 2022/8/5 15:55
 * @description:
 */
public class DateUtil {

    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);

    /**
     * 日期转换为年月日时分秒毫秒类型字符串
     * 类似：20160820143430090
     * @param date 日期
     * @return
     * 年月日时分秒毫秒类型字符串
     */
    public static String date2StringMillisecond(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        return formatter.format(date);
    }

    /**
     * 日期转换为年月日时分秒字符串
     * 类似：20160820143430
     * @param date 日期
     * @return
     * 年月日时分秒类型字符串
     */
    public static String dateTransStringMillisecond(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return formatter.format(date);
    }


    /**
     * 转换为指定日期的零点零分零秒
     * 类似：Sun Aug 28 00:00:00 CST 2016
     * @param date 指定的日期
     * @return
     */
    public static Date toDate00(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat isoDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        try {
            // 2016-08-29T00:00:00.000+0800
            String isoDateString = isoDateFormat.format(df.parse(df.format(date)));
            return isoDateFormat.parse(isoDateString);
        } catch (ParseException e) {
            logger.error("转换为指定日期的零点零分零秒异常：" + e.getMessage());
        }
        return null;
    }

    /**
     * 转换为指定日期的第二天0点0分0秒
     * 类似：Sun Aug 29 00:00:00 CST 2016
     * @param date 指定的日期
     * @return
     */
    public static Date toSecordDate00(Date date) {
        if (date == null) {
            return null;
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat isoDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        try {
            Date date1 = df.parse(df.format(date));
            // 2016-08-29T00:00:00.000+0800
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date1);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + 1);
            String isoDateString = isoDateFormat.format(calendar.getTime());
            return isoDateFormat.parse(isoDateString);
        } catch (ParseException e) {
            logger.error("转换为指定日期的第二天0点0分0秒异常：" + e.getMessage());
        }
        return null;
    }

    public static Date string2Date(String dateString) {
        dateString = dateString.trim();
        Date date = null;
        if (dateString == null || dateString.isEmpty()) {
            return null;
        }
        if (dateString.indexOf("-") != -1) {
            if (dateString.split("-").length == 3) {
                if (dateString.indexOf(":") != -1) {
                    if (dateString.split(":").length == 3) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                        try {
                            date = simpleDateFormat.parse(dateString);
                        } catch (ParseException e) {
                            logger.error("字符串转时间异常：" + e.getMessage());
                        }
                    } else if (dateString.split(":").length == 2) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm");
                        try {
                            date = simpleDateFormat.parse(dateString);
                        } catch (ParseException e) {
                            logger.error("字符串转时间异常：" + e.getMessage());
                        }
                    }
                } else if (dateString.indexOf("/") != -1) {
                    if (dateString.split("/").length == 3) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH/mm/ss");
                        try {
                            date = simpleDateFormat.parse(dateString);
                        } catch (ParseException e) {
                            logger.error("字符串转时间异常：" + e.getMessage());
                        }
                    } else if (dateString.split("/").length == 2) {
                        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH/mm");
                        try {
                            date = simpleDateFormat.parse(dateString);
                        } catch (ParseException e) {
                            logger.error("字符串转时间异常：" + e.getMessage());
                        }
                    }
                } else {
                    int index = dateString.lastIndexOf("-");
                    dateString = dateString.substring(0, dateString.length() < (index + 3) ? dateString.length() : index + 3).trim();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        date = simpleDateFormat.parse(dateString);
                    } catch (ParseException e) {
                        logger.error("字符串转时间异常：" + e.getMessage());
                    }
                }
            }
        } else if (dateString.indexOf("/") != -1) {
            if (dateString.indexOf(":") != -1) {
                if (dateString.lastIndexOf("/") < dateString.indexOf(":")) {
                    if (dateString.split("/").length == 3) {
                        if (dateString.indexOf(":") != -1) {
                            if (dateString.split(":").length == 3) {
                                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                                try {
                                    date = simpleDateFormat.parse(dateString);
                                } catch (ParseException e) {
                                    logger.error("字符串转时间异常：" + e.getMessage());
                                }
                            } else if (dateString.split(":").length == 2) {
                                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm");
                                try {
                                    date = simpleDateFormat.parse(dateString);
                                } catch (ParseException e) {
                                    logger.error("字符串转时间异常：" + e.getMessage());
                                }
                            }
                        } else {
                            int index = dateString.lastIndexOf("/");
                            dateString = dateString.substring(0, dateString.length() < (index + 3) ? dateString.length() : index + 3).trim();
                            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
                            try {
                                date = simpleDateFormat.parse(dateString);
                            } catch (ParseException e) {
                                logger.error("字符串转时间异常：" + e.getMessage());
                            }
                        }
                    }
                }
            } else if (dateString.split("/").length == 3) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd");
                try {
                    date = simpleDateFormat.parse(dateString);
                } catch (ParseException e) {
                    logger.error("字符串转时间异常：" + e.getMessage());
                }
            } else if (dateString.split("/").length == 4) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH/mm");
                try {
                    date = simpleDateFormat.parse(dateString);
                } catch (ParseException e) {
                    logger.error("字符串转时间异常：" + e.getMessage());
                }
            } else if (dateString.split("/").length > 4) {
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy/MM/dd HH/mm/ss");
                try {
                    date = simpleDateFormat.parse(dateString);
                } catch (ParseException e) {
                    logger.error("字符串转时间异常：" + e.getMessage());
                }
            }
        }
        if (date == null) {
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            try {
                date = simpleDateFormat.parse(dateString);
            } catch (ParseException e) {
                logger.error("字符串转时间异常：" + e.getMessage());
            }
        }
        return date;
    }

    // 计算与date相差的天数
    public static Date getNextOrLastDay(Date date, int i) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_MONTH, i);
        date = calendar.getTime();
        return date;
    }

    public static List<Date> countDay(Date start_time, Date end_time) {
        List<Date> dateList = new ArrayList<Date>();
        Calendar startDay = Calendar.getInstance();
        Calendar endDay = Calendar.getInstance();
        dateList.add(start_time);
        startDay.setTime(start_time);
        endDay.setTime(end_time);

        dateList = printDay(startDay, endDay, dateList);
        dateList.add(end_time);
        return dateList;

    }

    private static List<Date> printDay(Calendar startDay, Calendar endDay, List<Date> dateList) {

        // 给出的日期开始日比终了日大则不执行打印
        if (startDay.compareTo(endDay) >= 0) {
            return null;
        }
        // 现在打印中的日期
        Calendar currentPrintDay = startDay;
        while (true) {
            // 日期加一
            currentPrintDay.add(Calendar.DATE, 1);
            // 日期加一后判断是否达到终了日，达到则终止打印
            if (currentPrintDay.compareTo(endDay) == 0) {
                break;
            }
            Date date = currentPrintDay.getTime();
            dateList.add(date);
        }
        return dateList;
    }

    // 计算某天的开始时间和结束时间
    public static Map<String, Object> getStartANDEndTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);

        Date start = calendar.getTime();

        calendar.add(Calendar.DAY_OF_MONTH, 1);
        calendar.add(Calendar.SECOND, -1);

        Date end = calendar.getTime();

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("start_time", start);
        map.put("end_time", end);

        return map;
    }

    /**
     * 把毫秒转化成日期
     * @param dateFormat(日期格式，例如：MM/ dd/yyyy HH:mm:ss)
     * @param millSec(毫秒数)
     * @return
     */
    public static String transferLongToDate(String dateFormat, Long millSec) {
        if (dateFormat == null || dateFormat.trim().equals("")) {
            dateFormat = "yyyy-MM-dd HH:mm";
        }
        SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
        Date date = new Date(millSec);
        return sdf.format(date);
    }

    /**
     * @author liyafei
     * @desc  计算时间差
     * @param type  计算的内容，天(day),小时(hour)，分(minutes)
     * @param startDate 开始时间
     * @param endDate    结束时间
     * @return
     * @throws ParseException
     */
    public static int countTime(String type, Date startDate, Date endDate) {
        SimpleDateFormat simpleFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm");
        if (null == type || null == startDate || null == endDate) {
            throw new NullPointerException("param is null");
        }
        int count = 0;

        try {
            if ("day".equals(type)) {
                String fromDate = simpleFormat.format(startDate);
                String toDate = simpleFormat.format(endDate);
                long from = simpleFormat.parse(fromDate).getTime();
                long to = simpleFormat.parse(toDate).getTime();
                count = (int) ((to - from) / (1000 * 60 * 60 * 24));
            } else if ("hour".equals(type)) {
                String fromDate = simpleFormat.format(startDate);
                String toDate = simpleFormat.format(endDate);
                long from = simpleFormat.parse(fromDate).getTime();
                long to = simpleFormat.parse(toDate).getTime();
                count = (int) ((to - from) / (1000 * 60 * 60));
            } else if ("minutes".equals(type)) {
                String fromDate = simpleFormat.format(startDate);
                String toDate = simpleFormat.format(endDate);
                long from = simpleFormat.parse(fromDate).getTime();
                long to = simpleFormat.parse(toDate).getTime();
                count = (int) ((to - from) / (1000 * 60));
            } else {
                throw new IllegalArgumentException("param errror");
            }
        } catch (ParseException e) {
            logger.error("计算时间差异常：" + e.getMessage());
        }

        return count;
    }

    public static int compareDate(Date dt1, Date dt2) {
        if (null == dt1 || null == dt2) {
            throw new NullPointerException("param is null");
        }
        if (dt1.getTime() > dt2.getTime()) {
            return 1;
        } else if (dt1.getTime() < dt2.getTime()) {
            return -1;
        } else {// 相等
            return 0;
        }
    }

    public static int daysBetween(Date smdate, Date bdate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        try {
            smdate = sdf.parse(sdf.format(smdate));
            bdate = sdf.parse(sdf.format(bdate));
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Calendar cal = Calendar.getInstance();
        cal.setTime(smdate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(bdate);
        long time2 = cal.getTimeInMillis();
        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        return Integer.parseInt(String.valueOf(between_days));
    }

    /**
     * 得到几天后的时间
     * @param d
     * @param day
     * @return
     */
    public static Date getDateAfter(Date d,int day){
        Calendar now =Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE,now.get(Calendar.DATE)+day);
        return now.getTime();
    }

    /**
     * 将时间转换为时间戳
     * @param time
     * @return
     */
    public static String dateToStamp(Date time){
        String res;
        long ts = time.getTime();
        res = String.valueOf(ts);
        return res;
    }

    /**
     * 获取指定日期所在天的 00:00:00
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getBeginOfDay(Date date) {
        // 获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        String begin = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime()) + " 00:00:00";

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return dateFormat.parse(begin);
        } catch (ParseException e) {
            logger.error(e.getMessage());
        }
        return date;
    }

    /**
     * 获取指定日期所在天的前一天 00:00:00
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getBeginOfYesterday(Date date) {
        long day = 24 * 60 * 60 * 1000;
        return getBeginOfDay(new Date(date.getTime() - day));
    }

    /**
     * 获取指定日期所在天的 23:59:59
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getEndOfDay(Date date) {
        // 获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        String end = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime()) + " 23:59:59";

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return dateFormat.parse(end);
        } catch (ParseException e) {
            logger.error(e.getMessage());
        }
        return date;

    }

    /**
     * 获取指定日期所在天的前一天 23:59:59
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getEndOfYesterday(Date date) {
        long day = 24 * 60 * 60 * 1000;
        return getEndOfDay(new Date(date.getTime() - day));
    }


    /**
     * 获取指定日期所在月的第一天的 00:00:00
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getFirstDayOfMonth(Date date)  {
        //获取当前月第一天：
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        c.set(Calendar.DAY_OF_MONTH,1);//设置为1号,当前日期既为本月第一天
        String first = new SimpleDateFormat("yyyy-MM-dd").format(c.getTime())+" 00:00:00";

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return dateFormat.parse(first);
        } catch (ParseException e) {
            logger.error(e.getMessage());
        }
        return date;

    }

    /**
     * 获取指定日期所在月的上一个月的第一天的 00:00:00
     * @param date
     * @return
     */
    public static Date getFirstDayOfLastMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        return getFirstDayOfMonth(calendar.getTime());
    }

    /**
     * 获取指定日期所在月的最后一天的 23:59:59
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date getLastDayOfMonth(Date date)  {

        //获取当前月最后一天
        Calendar ca = Calendar.getInstance();
        ca.setTime(date);
        ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
        String last = new SimpleDateFormat("yyyy-MM-dd").format(ca.getTime()) +" 23:59:59";
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            return dateFormat.parse(last);
        } catch (ParseException e) {
            logger.error(e.getMessage());
        }
        return date;
    }

    /**
     * 获取指定日期所在月的上一个月的最后一天的 23:59:59
     * @param date
     * @return
     */
    public static Date getLastDayOfLastMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -1);
        return getLastDayOfMonth(calendar.getTime());
    }

    /**
     * 获取指定日期所在月的上n个月的最后一天的 23:59:59
     * @param date
     * @return
     */
    public static Date getLastDayOfVariableMonth(Date date,int n) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH, -n);
        return getLastDayOfMonth(calendar.getTime());
    }

    /**
     * @author:JackRen
     * @Description:获取指定日期的第几个月
     * @date:2021年1月15日下午4:09:18
     * @param date
     * @return 第几个月
     */
    public static int getMonthOfVariableDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.MONTH)+1;
    }

    /**
     * @author:JackRen
     * @Description:获取指定日期的第几天
     * @date:2021年1月15日下午4:09:18
     * @param date
     * @return 第几天
     */
    public static int getDayOfVariableDate(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar.get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 得到几天前的时间
     * @param d
     * @param day
     * @return
     */
    public static Date getDateBefore(Date d,int day){
        Calendar now =Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.DATE,now.get(Calendar.DATE)-day);
        return now.getTime();
    }

    /**
     * 得到几小时前的时间
     * @param d
     * @param hour
     * @return
     */
    public static Date getDateHourBefore(Date d,int hour){
        Calendar now =Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.HOUR_OF_DAY,now.get(Calendar.HOUR_OF_DAY)-hour);
        return now.getTime();
    }

    public static Date obtainDateByMills(Long time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        return calendar.getTime();
    }

    /**
     * 得到几分钟前的时间
     * @param d
     * @param minute
     * @return
     */
    public static Date getDateMinuteBefore(Date d, int minute){
        Calendar now =Calendar.getInstance();
        now.setTime(d);
        now.set(Calendar.MINUTE,now.get(Calendar.MINUTE)-minute);
        return now.getTime();
    }

    public static void main(String[] args) {
//            Long gather_time = Long.parseLong("1611972207000");
        System.out.println(getDateHourBefore(new Date(), 23));

    }

}
